package com.berry.MedCheck;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.TouchDelegate;
import android.view.View;
import android.view.Window;
import android.widget.*;
import com.berry.MedCheck.db.DBMonitorService;
import com.berry.MedCheck.db.UserDB;
import com.berry.MedCheck.export.ExportCsvThread;
import com.berry.MedCheck.widget.LineChart;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: Airay.Rong
 * Date: 13-12-4
 * Time: 下午2:38
 * To change this template use File | Settings | File Templates.
 */
public class GraphActivity extends BaseActivity implements LineChart.loadDataCallback, View.OnClickListener {
	private static final int LOAD_DATA_COUNT = 1;
	private static final int DATA_NUM_PER_PAGE = Utils.GRAPHY_POINT_NUM;  //这个数字必须比上边的大。

	private Button mBtnExport;
	private ImageView mBtnPreHour;
	private ImageView mBtnNextHour;
	private TextView mTVValueSpo2;
	private TextView mTVValuePR;
	private LineChart mChart;
	private long mCurrentUserID = 0;
	private TextView mTVMonth;
	private static final String[] PROJECTION = new String[]{
			UserDB.DBColumns._ID, // 0
			UserDB.DBColumns.USERID, // 2
			UserDB.DBColumns.DATE, // 3
			UserDB.DBColumns.SPO2, // 4
			UserDB.DBColumns.PR, // 5
			UserDB.DBColumns.PI, // 6
	};
	ArrayList<Map<String, Long>> arrayData = new ArrayList<Map<String, Long>>();
	private Cursor mCursor;
	private ProgressDialog progressDialog = null;
	private String EXPORT_PATH;
	private final String EXPORT_FILE_NAME = "export.csv";


	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.graph_activity);
		mChart = (LineChart) findViewById(R.id.chart);
		mBtnExport = (Button) findViewById(R.id.btn_export);
		mBtnExport.setOnClickListener(this);
		mBtnPreHour = (ImageView) findViewById(R.id.pri_hour);
		mBtnPreHour.setOnClickListener(this);
		mBtnNextHour = (ImageView) findViewById(R.id.next_hour);
		mBtnNextHour.setOnClickListener(this);
		enlargeTouchRegion();
		mTVValueSpo2 = (TextView) findViewById(R.id.tv_spo2);
		mTVValuePR = (TextView) findViewById(R.id.tv_pr);

		mTVMonth = (TextView) findViewById(R.id.tv_month);

		Readreference_CurrentUserName();
		getUserDataCursor();
		loadFirstData();
		mChart.setLoadDataCallback(this);
		mChart.setTextSize(getResources().getDimension(R.dimen.linechart_title_text_size),
				getResources().getDimension(R.dimen.linechart_level_text_size),
				getResources().getDimension(R.dimen.linechart_value_text_size));
		//mChart.setLineWidth(getResources().getDimension(R.dimen.linechart_line_width));
		mChart.setLineWidth(20);
		mChart.setDateTextView(mTVMonth);
		mChart.setValueTextView(mTVValueSpo2, mTVValuePR);
		//printData();
		setupMenuCallback();

	}
	public void enlargeTouchRegion() {
		final LinearLayout mContainPri = (LinearLayout) findViewById(R.id.container_pri_hour);
		mContainPri.post(new Runnable() {
			@Override
			public void run() {
				Rect rc = new Rect();
				mBtnPreHour.getHitRect(rc);
				rc.right = rc.right * 5;
				mContainPri.setTouchDelegate(new TouchDelegate(rc, mBtnPreHour));
			}
		});
		final LinearLayout mContainNext = (LinearLayout) findViewById(R.id.container_next_hour);
		mContainNext.post(new Runnable() {
			@Override
			public void run() {
				Rect rc = new Rect();
				mBtnNextHour.getHitRect(rc);
				rc.left = rc.left - 100;
				mContainNext.setTouchDelegate(new TouchDelegate(rc, mBtnNextHour));
			}
		});
	}

	private void setupMenuCallback() {
		mListener = new MenuCallback() {
			@Override
			public void onMenuClick(int id) {
				finish();
			}
		};
	}
	private void printData() {
		int i = 0;
		mCursor.moveToLast();
		int max = mCursor.getCount();
		for (int j = 0; j < max; j++) {
			int iSpo2 = mCursor.getColumnIndex(UserDB.DBColumns.SPO2);
			int dataSpo2 = mCursor.getInt(iSpo2);
			Log.d("meauserData", "Spo2=" + dataSpo2);
			mCursor.moveToPrevious();
		}
		mCursor.moveToFirst();
	}

	@Override
	protected void onResume() {
		super.onResume();
		//setTestDatas();
	}

	private void getUserDataCursor() {
		String selection = "userid=" + mCurrentUserID;
		mCursor = managedQuery(
				UserDB.DBColumns.MEASURE_URI,            // Use the default content URI for the provider.
				PROJECTION,                       // Return the note ID and title for each note.
				selection,                             // No where clause, return all records.
				null,                             // No where clause, therefore no where column values.
				UserDB.DBColumns.DEFAULT_MEAUSURE_SORT_ORDER  // Use the default sort order.
		);
		if (mCursor.getCount() == 0) {
			return;
		}
		mCursor.moveToFirst();
	}


	private void resetDataArray() {
		arrayData.clear();
		for (int i = 0; i < DATA_NUM_PER_PAGE; i++) {
			Map<String, Long> map = new HashMap<String, Long>();
			map.put(UserDB.DBColumns.SPO2, 0L);
			map.put(UserDB.DBColumns.PR, 0L);
			map.put(UserDB.DBColumns.DATE, 0L);
			arrayData.add(map);
		}
	}

	private void loadFirstData() {
		if (mCursor == null) {
			return;
		}
		//为了方便使用，最新的数据保存在第一位
		resetDataArray();
		if (mCursor.getCount() == 0) {
			return;
		}
		for (int i = 0; i < DATA_NUM_PER_PAGE; i++) {
			putOneData(i);
			if (mCursor.isLast()) {
				break;
			}
			mCursor.moveToNext();
		}
		mCursor.moveToFirst();
		mChart.setFullData(arrayData);
		//setMonthFromlastDate();
	}

	private void putOneData(int index) {
		try {
			int iSpo2 = mCursor.getColumnIndex(UserDB.DBColumns.SPO2);
			int iPr = mCursor.getColumnIndex(UserDB.DBColumns.PR);
			int iDate = mCursor.getColumnIndex(UserDB.DBColumns.DATE);
			int dataSpo2 = mCursor.getInt(iSpo2);
			int dataPR = mCursor.getInt(iPr);
			long dataDate = mCursor.getLong(iDate);
			Map<String, Long> map = new HashMap<String, Long>();
			map.put(UserDB.DBColumns.SPO2, (long) dataSpo2);
			map.put(UserDB.DBColumns.PR, (long) dataPR);
			map.put(UserDB.DBColumns.DATE, dataDate);
			arrayData.set(index, map);
		} catch (Exception e) {
		}


	}

	private void loadOldData() {
		//保持Cursor始终在Page开头位置。数据库为时间倒序排列。
		if (mCursor == null) {
			return;
		}
		int nCursorPos = mCursor.getPosition();
		if (mCursor.getCount() - nCursorPos == DATA_NUM_PER_PAGE) {
			//已经在最后，无法加载
			Log.d("meauserData", "The End");
			return;
		}
		if (mCursor.getCount() - nCursorPos - DATA_NUM_PER_PAGE >= LOAD_DATA_COUNT) {
			//能够加载完整的一页。
			Log.d("meauserData", "Load whole new Old data page");
			mCursor.moveToPosition(nCursorPos + LOAD_DATA_COUNT);
			for (int i = 0; i < DATA_NUM_PER_PAGE; i++) {
				putOneData(i);
				mCursor.moveToNext();
			}
			//Cursor回退到Page开头
			mCursor.moveToPosition(mCursor.getPosition() - DATA_NUM_PER_PAGE);

		} else {
			//无法加载完整一页
			Log.d("meauserData", "Load part new Old data page");
			int nLeftNum = mCursor.getCount() - nCursorPos - DATA_NUM_PER_PAGE;
			if (nLeftNum < 0) {
				return;
			}
			mCursor.moveToPosition(nCursorPos + nLeftNum);
			for (int i = 0; i < DATA_NUM_PER_PAGE; i++) {
				putOneData(i);
				mCursor.moveToNext();
			}
			//Cursor回退到Page开头
			mCursor.moveToPosition(mCursor.getPosition() - DATA_NUM_PER_PAGE);
		}
		mChart.setFullData(arrayData);
	}

	private void loadNewData() {
		//arrayData中的前3个，移动到最后，然后加载3个信数据到arrayData中，保持折线图平稳
		//加载的个数由LOAD_DATA_COUNT确定。
		if (mCursor == null) {
			return;
		}
		int nCursorPos = mCursor.getPosition();
		if (nCursorPos <= 0) {
			Log.d("meauserData", "The Head");
			return;
		}
		if (nCursorPos >= LOAD_DATA_COUNT) {
			//加载完整数据
			Log.d("meauserData", "Load whole new New data page");
			//此时cursor正好在新加页的末尾，前移 LOAD_DATA_COUNT,然后正序加载
			mCursor.moveToPosition(nCursorPos - LOAD_DATA_COUNT);
			for (int i = 0; i < DATA_NUM_PER_PAGE; i++) {
				putOneData(i);
				mCursor.moveToNext();
			}
			mCursor.moveToPosition(mCursor.getPosition() - DATA_NUM_PER_PAGE);
		} else {
			//加载剩余数据
			Log.d("meauserData", "Load part new New data page");
			int nLeftNum = (DATA_NUM_PER_PAGE - nCursorPos);
			mCursor.moveToFirst();
			for (int i = 0; i < DATA_NUM_PER_PAGE; i++) {
				putOneData(i);
				mCursor.moveToNext();
			}
			mCursor.moveToFirst();
		}
		mChart.setFullData(arrayData);
	}

	private void loadPreHourData() {
		cursorSkipAHour(false);
	}

	private void loadNextHourData() {
		cursorSkipAHour(true);
	}

	private void cursorSkipAHour(boolean bNew) {
		boolean bFind = false;
		if (bNew == true) {  //跳到前一小时
			long nCurrnetTime = arrayData.get(0).get(UserDB.DBColumns.DATE);
			long nNewTime = nCurrnetTime + 1 * 60 * 60 * 1000;
			Log.d("AAAA", "CurTime=" + Utils.getFullDate(nCurrnetTime) + "; NewTime=" + Utils.getFullDate(nNewTime));
			while (mCursor.moveToPrevious()) {
				if (mCursor.isBeforeFirst()) {
					break;
				}
				int iDate = mCursor.getColumnIndex(UserDB.DBColumns.DATE);
				long dataDate = mCursor.getLong(iDate);
				if (dataDate >= nNewTime) {
					bFind = true;
					break;
				}
			}

		} else {   //跳到后一小时
			long nCurrnetTime = arrayData.get(DATA_NUM_PER_PAGE-1).get(UserDB.DBColumns.DATE);
			long nNewTime = nCurrnetTime - 1 * 60 * 60 * 1000;
			Log.d("AAAA", "CurTime=" + Utils.getFullDate(nCurrnetTime) + "; NewTime=" + Utils.getFullDate(nNewTime));
			while (mCursor.moveToNext()) {
				if (mCursor.isLast() || mCursor.isAfterLast()) {
					break;
				}
				int iDate = mCursor.getColumnIndex(UserDB.DBColumns.DATE);
				long dataDate = mCursor.getLong(iDate);
				if (dataDate <= nNewTime) {
					bFind = true;
					break;
				}
			}
		}
		if (bFind == false) {
			Log.d("AAAA", "bFind == false");
			Toast.makeText(this, R.string.no_data, Toast.LENGTH_SHORT).show();
			return;
		}

		resetDataArray();
		for (int i = 0; i < DATA_NUM_PER_PAGE; i++) {
			putOneData(i);
			if (mCursor.isLast()) {
				break;
			}
			mCursor.moveToNext();
		}
		mChart.setFullData(arrayData);

	}
	private void cursorSkip100(boolean bNew) {
		boolean bFind = false;
		int NUM = 100;
		if (bNew == true) {  //跳到前100
			int pos = mCursor.getPosition();
			if (pos == 0) {

			}else if (pos == DATA_NUM_PER_PAGE){

			}else if (pos <= NUM) {
				mCursor.moveToFirst();
				bFind = true;
			} else {
				mCursor.moveToPosition(pos - NUM);
				bFind = true;
			}

		} else {   //跳到后100
			int pos = mCursor.getPosition();
			int max = mCursor.getCount();
			if (mCursor.isAfterLast()) {

			} else {
				if (pos == max) {

				} else if (pos + NUM >= max) {   //超过最大值
					if (max < NUM) {
						if (max - DATA_NUM_PER_PAGE < 0) { //数据少于一页
							mCursor.moveToFirst();
						} else {
							mCursor.moveToPosition(max - DATA_NUM_PER_PAGE);
							bFind = true;
						}
					} else { //显示倒数100个
						mCursor.moveToPosition(max - NUM);
						bFind = true;
					}
				} else { //向后跳100
					mCursor.moveToPosition(pos + NUM);
					bFind = true;
				}
			}
		}
		if (bFind == false) {
			Log.d("AAAA", "bFind == false");
			Toast.makeText(this, R.string.no_data, Toast.LENGTH_SHORT).show();
			return;
		}
		resetDataArray();
		for (int i = 0; i < DATA_NUM_PER_PAGE; i++) {
			if ( mCursor.isAfterLast()) {
				break;
			}
			putOneData(i);
			mCursor.moveToNext();
		}
		mChart.setFullData(arrayData);

	}
	private void Readreference_CurrentUserName() {
		SharedPreferences sp = getSharedPreferences(Utils.PREFERENCE_NAME, 0);
		mCurrentUserID = sp.getLong(Utils.PRE_KEY_CURRENT_USER_ID, 0);

	}


	private void setTestDatas() {
		mChart.setLoadDataCallback(this);
		ArrayList<Integer> array = new ArrayList<Integer>(6);
		array.add((int) (Math.random() * 100));
		array.add((int) (Math.random() * 100));
		array.add((int) (Math.random() * 100));
		array.add((int) (Math.random() * 100));
		array.add((int) (Math.random() * 100));
		array.add((int) (Math.random() * 100));
		mChart.setData1List(array);

		ArrayList<Integer> array2 = new ArrayList<Integer>(6);
		array2.add((int) (Math.random() * 100));
		array2.add((int) (Math.random() * 100));
		array2.add((int) (Math.random() * 100));
		array2.add((int) (Math.random() * 100));
		array2.add((int) (Math.random() * 100));
		array2.add((int) (Math.random() * 100));
		mChart.setData2List(array2);


		ArrayList<Long> array3 = new ArrayList<Long>(6);
		array3.add(System.currentTimeMillis() - 150000);
		array3.add(System.currentTimeMillis() - 120000);
		array3.add(System.currentTimeMillis() - 90000);
		array3.add(System.currentTimeMillis() - 60000);
		array3.add(System.currentTimeMillis() - 30000);
		array3.add(System.currentTimeMillis() - 0);
		mChart.setTimeList(array3);
	}


	@Override
	public void loadData(boolean old) {
		if (old == true) {
			//加载旧数据
			loadOldData();
		} else {
			//加载新数据
			loadNewData();
		}
		//setMonthFromlastDate();
//		ArrayList<Integer> array = new ArrayList<Integer>(6);
//		array.add((int) (Math.random() * 100));
//		array.add((int) (Math.random() * 100));
//		array.add((int) (Math.random() * 100));
//		array.add((int) (Math.random() * 100));
//		array.add((int) (Math.random() * 100));
//		array.add((int) (Math.random() * 100));
//		mChart.setData1List(array);
//
//		ArrayList<Integer> array2 = new ArrayList<Integer>(6);
//		array2.add((int) (Math.random() * 100));
//		array2.add((int) (Math.random() * 100));
//		array2.add((int) (Math.random() * 100));
//		array2.add((int) (Math.random() * 100));
//		array2.add((int) (Math.random() * 100));
//		array2.add((int) (Math.random() * 100));
//		mChart.setData2List(array2);

		//To change body of implemented methods use File | Settings | File Templates.
	}

	private void setMonthFromlastDate() {
		Map<String, Long> map;
		map = arrayData.get(DATA_NUM_PER_PAGE-1);
		Long dateValue = map.get(UserDB.DBColumns.DATE);
		if (dateValue == 0) {
			map = arrayData.get(0);
			dateValue = map.get(UserDB.DBColumns.DATE);
		}
		String month = Utils.getMonth(dateValue);
		//mTVMonth.setText(month);

	}

	@Override
	public void onClick(View v) {
		if (v == mBtnExport) {
			if (progressDialog != null && progressDialog.isShowing()) {
				progressDialog.dismiss();
			}
			progressDialog = ProgressDialog.show(this, "", getString(R.string.exporting), true, true);
			startService(new Intent().setClass(this, DBMonitorService.class));
			try {
				startExport();
			} catch (IOException e) {
				showExportFailDialog(R.string.export_csv_fail);
				e.printStackTrace();
			}
		}
		if (v == mBtnPreHour) {
			//Log.d("AAAA", "Pri");
			//loadPreHourData();
			cursorSkip100(false);
		}
		if (v == mBtnNextHour) {
			//Log.d("AAAA", "Next");
			//loadNextHourData();
			cursorSkip100(true);

		}
	}

	public void startExport() throws IOException {
		String status = Environment.getExternalStorageState();
		if (status.equals("mounted")) {
			EXPORT_PATH = Environment.getExternalStorageDirectory() + "/" + getApplication().getPackageName();
			File mWorkingPath;
			mWorkingPath = new File(EXPORT_PATH);
			if (!mWorkingPath.exists()) {
				mWorkingPath.mkdirs();
			}
			File myfileSend = new File(EXPORT_PATH + "/" + EXPORT_FILE_NAME);
			if (myfileSend.exists()) {
				myfileSend.delete();
			}
			myfileSend.createNewFile();
			doExport(myfileSend);
		} else {
			showExportFailDialog(R.string.export_csv_fail_sd);
		}


	}

	public void doExport(File file) {
		try {
			FileWriter writer = new FileWriter(file);
			Log.d("ExportCSV", "file:" + file.getAbsolutePath());
			ExportCsvThread ec = new ExportCsvThread(this, mCursor, writer, mHandler);
			ec.run();
			writer.close();
		} catch (IOException e) {
			showExportFailDialog(R.string.export_csv_fail_sd);
			Log.d("ExportCSV", "IO exception", e);

		}
	}

	private final Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
				case Utils.HANDLE_MSG_EXPORT_DONE:
					if (progressDialog != null && progressDialog.isShowing()) {
						progressDialog.dismiss();
					}
					callEmail();
					break;
				case Utils.HANDLE_MSG_EXPORT_FAIL:
					showExportFailDialog(R.string.export_csv_fail_db);
					break;

			}
		}
	};

	private void showExportFailDialog(int strID) {
		if (progressDialog != null && progressDialog.isShowing()) {
			progressDialog.dismiss();
		}
		AlertDialog alert = new AlertDialog.Builder(this).create();
		alert.setCanceledOnTouchOutside(false);
		alert.show();

		Window window = alert.getWindow();
		window.setContentView(R.layout.my_alert_dialog);
		TextView tv = (TextView) window.findViewById(R.id.message);
		tv.setText(this.getResources().getText(strID));//
		Button btnCancel = (Button) window.findViewById(R.id.btn_cancel);
		btnCancel.setVisibility(View.GONE);
		Button btnOK = (Button) window.findViewById(R.id.btn_ok);
		btnOK.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
			}
		});
	}

	private void callEmail() {
		String fileName = EXPORT_PATH + "/" + EXPORT_FILE_NAME;
		File file = new File(fileName);
		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.putExtra("subject", file.getName()); //
		intent.putExtra("body", "ExportData"); //正文
		intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); //添加附件，附件为file对象
		intent.setType("application/octet-stream"); //其他的均使用流当做二进制数据来发送
		startActivity(intent); //调用系统的mail客户端进行发送
	}


}